﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Reflection;
using System.IO;
using System.Xml.Linq;
using System.Xml;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Diagnostics;

namespace Ghost.Tasks.Wiki.XApi
{
    public partial class XMember
    {
        [XmlIgnore]
        public MemberInfo memberInfo
        {
            get;
            set;
        }

        [XmlIgnore]
        public bool isPublic;

        public override string ToString()
        {
            return id;
        }

        [XmlIgnore]
        public TaskLoggingHelper log;
    }

    public class XMemberLiteral : XMember
    {
    }

    public static class XMemberExtensions
    {

        public static ITaskItem ToTaskItem(this XMember member)
        {
            return new TaskItem(member.wikiLink);
        }

        static XmlDocument _TempDocument;
        static XMemberExtensions()
        {
            _TempDocument = new XmlDocument();
            _TempDocument.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><Assembly xmlns=\"http://ghost-tasks.googlecode.com/Wiki/XmlDoc.xsd\"/>");
        }

        public static void BuildFileComments(this XMember output, XAssembly outputAssembly)
        {
            string inputDirectory = Path.GetDirectoryName(outputAssembly.inputAssembly.Location);
            string path = Path.Combine(inputDirectory, output.wikiLink) + ".comments";
            if (File.Exists(path))
            {
                output.BuildComments(File.ReadAllText(path));
            }
        }

        public static void BuildComments(this XMember output, XElement input)
        {
            if (input == null)
            {
                return;
            }
            BuildComments(output, input.Nodes().Aggregate("", (s, n) => n.ToString(SaveOptions.DisableFormatting)));
        }

        public static void BuildComments(this XMember output, string input)
        {
            output.comments = new XMemberComments();
            XmlDocumentFragment fragment = _TempDocument.CreateDocumentFragment();
            try
            {
                fragment.InnerXml = input;
            }
            catch (XmlException)
            {
                fragment.InnerXml = System.Security.SecurityElement.Escape(input);
            }

            List<XmlNode> nodes = fragment.ChildNodes.OfType<XmlNode>().Select(n => _TempDocument.ImportNode(n, true)).ToList();
            output.comments.Any = nodes.ToArray();
        }

        /// <summary>
        /// Logs the warning. In debug mode, lists the superset of things we are sifting through
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="assembly">The assembly.</param>
        /// <param name="supersetEnumerator">The enumerator.</param>
        /// <param name="message">The message.</param>
        /// <param name="messageArgs">The message args.</param>
        public static void LogWarningFindFailed<T>(this XMember member, Func<IEnumerable<T>> supersetEnumerator, string message, params object[] messageArgs)
        {
#if DEBUG
            List<T> options = new List<T>(supersetEnumerator());
#endif

            member.LogWarning(message, messageArgs);
        }

        public static void LogWarning(this XMember member, string message, params object[] messageArgs)
        {
            member.log.LogWarning(message, messageArgs);
            Debug.WriteLine(string.Concat("W:", string.Format(message, messageArgs)));
        }

        public static void LogVerbose(this XMember member, string message, params object[] messageArgs)
        {
            member.log.LogMessage(MessageImportance.Low, message, messageArgs);
            Debug.WriteLine(string.Concat("V:", string.Format(message, messageArgs)));
        }

    }
}
